﻿using System;
using System.Collections.Generic;
using System.Text;

using Cabal.Kernel;
using System.Xml;

namespace Cabal.Kernel.Output
{
    public class HostIP : IRule
    {
        public HostIP(MissionCollection running)
        {
            _running = running;
        }

        /* XML格式参考技术文档 */

        static string RuleType_HostIP = "HostIP";
        static string Host_Default = "Default";

        MissionCollection _running;
        Uri Host; // equal null if host is defult
        int MaxCount;
        int Time;

        #region IRule 成员

        public void FormXmlNode(System.Xml.XmlNode basenode)
        {
            XmlNode tmpnode;

            tmpnode = basenode.SelectSingleNode("RuleType");
            if (tmpnode.InnerText != RuleType_HostIP)
                throw new Exception("限速规则读取异常.节点不属于HostIP限速规则");

            tmpnode = basenode.SelectSingleNode("Host");
            if (tmpnode.InnerText != Host_Default)
                Host = new Uri(tmpnode.InnerText);

            tmpnode = basenode.SelectSingleNode("Time");
            Time = int.Parse(tmpnode.InnerText);

            tmpnode = basenode.SelectSingleNode("RequestCount");
            MaxCount = int.Parse(tmpnode.InnerText);

            tmpnode = null;
        }

        public System.Xml.XmlNode ToXmlNode(XmlNode emptynode)
        {
            XmlDocument doc = emptynode.OwnerDocument;
            XmlNode tmpnode;

            emptynode.RemoveAll();
            emptynode.InnerText = "Rule";

            tmpnode = doc.CreateElement("RuleType");
            tmpnode.InnerText = RuleType_HostIP;
            emptynode.AppendChild(tmpnode);

            tmpnode = doc.CreateElement("Host");
            tmpnode.InnerText = (Host == null) ? Host_Default : Host.Authority;
            emptynode.AppendChild(tmpnode);

            tmpnode = doc.CreateElement("Time");
            tmpnode.InnerText = Time.ToString();
            emptynode.AppendChild(tmpnode);

            tmpnode = doc.CreateElement("RequestCount");
            tmpnode.InnerText = MaxCount.ToString();
            emptynode.AppendChild(tmpnode);

            doc = null;

            return emptynode;
        }

        public CheckResult Check(Mission m)
        {
            if (RuleApply(m))
            {
                string source = ((HttpRequestMission)m.Data).GetSourceIP();
                List<Mission> result = _running.SelectPair(MissionData.Flag_SourceIP, source);

                _running.GcByTime(result, Time); //回收过期的冗余任务

                if (result.Count <= MaxCount) //小于最大数量
                {
                    return CheckResult.NotMatch; //规则未触发
                }
                else
                {
                    return CheckResult.Match; //规则触发
                }
            }
            else
            {
                return CheckResult.NotApply;
            }
        }

        bool RuleApply(Mission m)
        {
            if (m.Data is HttpRequestMission)
            {
                HttpRequestMission request = m.Data as HttpRequestMission;
                if (Host == null || Host.IsBaseOf(request.GetRequestUri()))
                    return true;
            }
            return false;
        }

        #endregion

        #region IRule 成员

        public string GetRuleType()
        {
            return RuleType_HostIP;
        }

        #endregion
    }
}
